﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using l1cs.server.model.skill;
using l1cs.server.server.types;

namespace l1cs.server.model
{
    public class MpRegeneration
    {
        private static Logger _log = Logger.getLogger( typeof( MpRegeneration ).FullName );

        private L1PcInstance _pc;

        private int _regenPoint = 0;

        private int _curPoint = 4;

        public MpRegeneration( L1PcInstance pc )
        {
            _pc = pc;
        }

        // 特別 TODO
        public void cancel() { }

        public void setState( int state )
        {
            if ( _curPoint < state )
            {
                return;
            }

            _curPoint = state;
        }

        public void run( object state )
        {
            if ( _pc.isDead() )
            {
                return;
            }

            _regenPoint += _curPoint;
            _curPoint = 4;

            if ( 64 <= _regenPoint )
            {
                _regenPoint = 0;
                regenMp();
            }
        }

        public void regenMp()
        {
            int baseMpr = 1;
            int wis = _pc.getWis();
            if ( wis == 15 || wis == 16 )
            {
                baseMpr = 2;
            }
            else if ( wis >= 17 )
            {
                baseMpr = 3;
            }

            if ( _pc.hasSkillEffect( L1SkillId.STATUS_BLUE_POTION ) )
            { // ブルーポーション使用中
                if ( wis < 11 )
                { // WIS11未満でもMPR+1
                    wis = 11;
                }
                baseMpr += wis - 10;
            }
            if ( _pc.hasSkillEffect( L1SkillId.MEDITATION ) )
            { // メディテーション中
                baseMpr += 5;
            }
            if ( _pc.hasSkillEffect( L1SkillId.CONCENTRATION ) )
            { // コンセントレーション中
                baseMpr += 2;
            }
            if ( L1HouseLocation.isInHouse( _pc.getX(), _pc.getY(), _pc.getMapId() ) )
            {
                baseMpr += 3;
            }
            if ( _pc.getMapId() == 16384 || _pc.getMapId() == 16896
                    || _pc.getMapId() == 17408 || _pc.getMapId() == 17920
                    || _pc.getMapId() == 18432 || _pc.getMapId() == 18944
                    || _pc.getMapId() == 19968 || _pc.getMapId() == 19456
                    || _pc.getMapId() == 20480 || _pc.getMapId() == 20992
                    || _pc.getMapId() == 21504 || _pc.getMapId() == 22016
                    || _pc.getMapId() == 22528 || _pc.getMapId() == 23040
                    || _pc.getMapId() == 23552 || _pc.getMapId() == 24064
                    || _pc.getMapId() == 24576 || _pc.getMapId() == 25088 )
            { // 宿屋
                baseMpr += 3;
            }
            if ( ( _pc.getLocation().isInScreen( new Point( 33055, 32336 ) )
                    && _pc.getMapId() == 4 && _pc.isElf() ) )
            {
                baseMpr += 3;
            }
            if ( _pc.hasSkillEffect( L1SkillId.COOKING_1_2_N )
                    || _pc.hasSkillEffect( L1SkillId.COOKING_1_2_S ) )
            {
                baseMpr += 3;
            }
            if ( _pc.hasSkillEffect( L1SkillId.COOKING_2_4_N )
                    || _pc.hasSkillEffect( L1SkillId.COOKING_2_4_S )
                    || _pc.hasSkillEffect( L1SkillId.COOKING_3_5_N )
                    || _pc.hasSkillEffect( L1SkillId.COOKING_3_5_S ) )
            {
                baseMpr += 2;
            }
            if ( _pc.getOriginalMpr() > 0 )
            { // オリジナルWIS MPR補正
                baseMpr += _pc.getOriginalMpr();
            }

            int itemMpr = _pc.getInventory().mpRegenPerTick();
            itemMpr += _pc.getMpr();

            if ( _pc.get_food() < 3 || isOverWeight( _pc ) )
            {
                baseMpr = 0;
                if ( itemMpr > 0 )
                {
                    itemMpr = 0;
                }
            }
            int mpr = baseMpr + itemMpr;
            int newMp = _pc.getCurrentMp() + mpr;
            if ( newMp < 0 )
            {
                newMp = 0;
            }
            _pc.setCurrentMp( newMp );
        }

        private bool isOverWeight( L1PcInstance pc )
        {
            // エキゾチックバイタライズ状態、アディショナルファイアー状態であれば、
            // 重量オーバーでは無いとみなす。
            if ( pc.hasSkillEffect( L1SkillId.EXOTIC_VITALIZE )
                    || pc.hasSkillEffect( L1SkillId.ADDITIONAL_FIRE ) )
            {
                return false;
            }

            return ( 120 <= pc.getInventory().getWeight240() ) ? true : false;
        }
    }
}
